home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 9 / FM Towns Free Software Collection 9.iso / t_os / tool / pcom / src / comp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  8.7 KB  |  431 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <egb.h>
  5. #include <nslib.h>
  6. #include "pc_inc.h"
  7.  
  8. #define BUFFER        (16384)
  9.  
  10.  
  11. static void equation( int *d, int h, int *u )
  12. {
  13.     int i, j, k;
  14.     int tmp,
  15.         m[3][4] = { { 65536, 16384,     0, 0 },
  16.                     { 16384, 65536, 16384, 0 },
  17.                     {     0, 16384, 65536, 0 } };
  18.  
  19.     /* 行列の作成 */
  20.     tmp = MUL( h, h );
  21.     for( i=0; i<3; i++ )
  22.         m[i][3] = DIV( ( d[i+2] - d[i+1]*2 + d[i] )*3, 2*tmp );
  23.  
  24.     /* 方程式を解く */
  25.     for( i=0; i<3; i++ ) /* 引く行 */
  26.         for( j=0; j<3; j++ ) /* 引かれる行 */
  27.             if ( i != j )
  28.                 for( k=0; k<4; k++ ) /* 列 */
  29.                     m[j][k] -= MUL( m[i][k], m[j][i] );
  30.     for( i=0; i<3; i++ )
  31.         u[i+1] = m[i][3];
  32. }
  33.  
  34. static void equation2( int *d, int h, int *u )
  35. {
  36.     int tmp=MUL(h,h);
  37.  
  38.     u[2] = u[3];
  39.  
  40.     /* 方程式を解く */
  41.     u[3] = ( DIV( (d[2]-d[3]*2+d[4])*6, tmp ) -u[2] )/4;
  42. }
  43.  
  44. static void rate( schar *pcm, schar *buf, int is, int os )
  45. {
  46.     int i, idx=0, d[]={0,0,0,0,0}, u[]={0,0,0,0,0}, h, re, t1, t2,
  47.         si=0, di=0;
  48.  
  49.     h = FIX(os) / is;
  50.  
  51.     _fill_d( d, FIX((int)pcm[0]), 2 );
  52.     for( i=2; i<5; i++ )
  53.         d[i] = FIX((int)pcm[idx++]);
  54.  
  55.     equation( d, h, u );
  56.  
  57.     for( i=0; i<is; i++ )
  58.         {
  59.         while( si < h )
  60.             {
  61.             t1 = si-h;
  62.             t2 = MUL( h, h );
  63.             re = DIV(
  64.                     - MUL( MUL(u[2],t1), MUL(t1,t1) )
  65.                     + MUL( MUL(u[3],si), MUL(si,si) )
  66.                     + MUL( ( 6*d[3] - MUL(u[3], t2) ), si )
  67.                     - MUL( ( 6*d[2] - MUL(u[2], t2) ), t1 )
  68.                     , (6*h) );
  69.  
  70.             if ( re < 0 )
  71.                 {
  72.                 re = -INT(-re);
  73.                 if ( re < -127 )
  74.                     re = -127;
  75.                 }
  76.             else
  77.                 {
  78.                 re = INT(re);
  79.                 if ( re > 126 )
  80.                     re = 126;
  81.                 }
  82.             buf[di++] = (schar)re;
  83.             si += FIX(1);
  84.             }
  85.         si -= h;
  86.  
  87.         _copy_d( d, d+1, 4 );
  88.         if ( idx < is )
  89.             d[4] = FIX( (int)pcm[idx++] );
  90.         else
  91.             d[4] = FIX( (int)pcm[is-1] );
  92.         equation2( d, h, u );
  93.         }
  94. }
  95.  
  96. void ctosc( schar *src, int n )
  97. {
  98.     int i;
  99.  
  100.     for( i=0; i<n; i++ )
  101.         if ( src[i] & 0x80 )
  102.             src[i] &= 127;
  103.         else
  104.             src[i] = -src[i];
  105. }
  106.  
  107. void sctoc( schar *src, int n )
  108. {
  109.     int i;
  110.  
  111.     for( i=0; i<n; i++ )
  112.         if ( src[i] & 0x80 )
  113.             src[i] = (src[i]^255)+1;
  114.         else
  115.             src[i] |= 128;
  116. }
  117.  
  118. static void predict( schar *pcm, int n )
  119. {
  120.     int i, a, a0=0, a1=0, tmp;
  121.  
  122.     for( i=2; i<n; i++ )
  123.         {
  124.         a = 2*( (int)pcm[i-1]+a1 ) - ( (int)pcm[i-2]+a0 );
  125.         if ( a > 127 )
  126.             a = 127;
  127.         else if ( a < -127 )
  128.             a = -127;
  129.         a0 = a1; a1 = a;
  130.         tmp = (int)pcm[i] - a;
  131.         if ( tmp < -128 )
  132.             tmp = -128;
  133.         else if ( tmp > 127 )
  134.             tmp = 127;
  135.         pcm[i] = (schar)tmp;
  136.         }
  137. }
  138.  
  139. static void predict_decode( schar *pcm, int n )
  140. {
  141.     int i, a, tmp;
  142.  
  143.     for( i=2; i<n; i++ )
  144.         {
  145.         a = 2*(int)pcm[i-1] - (int)pcm[i-2];
  146.         if ( a > 127 )
  147.             a = 127;
  148.         else if ( a < -127 )
  149.             a = -127;
  150.         tmp = (int)pcm[i] + a;
  151.         pcm[i] = BYTE( &tmp );
  152.         }
  153. }
  154.  
  155. static void dpcm( schar *pcm, int n )
  156. {
  157.     int i, e=0, val;
  158.  
  159.     val = pcm[0];
  160.     for( i=1; i<BUFFER; i++ )
  161.         {
  162.         e = (int)(pcm[i]-val);
  163.         if ( e < -128 )
  164.             e = -128;
  165.         else if ( e > 127 )
  166.             e = 127;
  167.         pcm[i] = (schar)e;
  168.         val += e;
  169.         }
  170. }
  171.  
  172. static void dpcm_decode( schar *pcm, int n )
  173. {
  174.     int i;
  175.  
  176.     for( i=1; i<BUFFER; i++ )
  177.         pcm[i] += pcm[i-1];
  178. }
  179.  
  180. static int fft_comp( schar *pcm )
  181. {
  182.     int i, max, si, di=BUFFER/N;
  183.     short *rl, *im;
  184.     schar *buf;
  185.  
  186.     rl = malloc( N*4 );
  187.     if ( rl == NULL ) return (-1);
  188.     im = rl+N;
  189.     buf = malloc( BUFFER );
  190.     if ( buf == NULL )
  191.         {
  192.         free( rl );
  193.         return (-1);
  194.         }
  195.  
  196.     for( si=0; si<BUFFER; si+=N )
  197.         {
  198.         /* FFT */
  199.         for( i=0; i<N; i++ )
  200.             rl[i] = (short)pcm[si+i];
  201.         _fill_w( im, 0, N );
  202.         time_window( rl );
  203.         fft( rl, im, 0 );
  204.         for( i=N/2-1; rl[i]*rl[i]+im[i]*im[i] <= 9 && i>1; i-- );
  205.         buf[si/N] = (schar)i;
  206.         max = (i+1)*2;
  207.         if ( di+max > BUFFER )
  208.             { free( rl ); free ( buf ); return (-2); }
  209.         rate( pcm+si, buf+di, N, max );
  210.         di += max;
  211.         }
  212.     _copy_b( pcm, buf, di );
  213.  
  214.     free( rl );
  215.     free( buf );
  216.     return ( di );
  217. }
  218.  
  219. static int fft_exp( schar *pcm, schar next )
  220. {
  221.     int src, di, si=BUFFER/N;
  222.     schar *buf;
  223.  
  224.     buf = malloc( BUFFER );
  225.     if ( buf == NULL ) return (-1);
  226.  
  227.     for( di=0; di<BUFFER; di+=N )
  228.         {
  229.         src = ((int)pcm[di/N]+1)*2;
  230.         rate( pcm+si, buf+di, src, N );
  231.         si += src;
  232.         }
  233.     for( di=N; di<BUFFER; di+=N )
  234.         buf[di-1] = (schar)( ((int)buf[di-2]+(int)buf[di])/2 );
  235.     buf[BUFFER-1] = (schar)( ((int)buf[BUFFER-2]+(int)next)/2 );
  236.  
  237.     _copy_b( pcm, buf, BUFFER );
  238.  
  239.     free( buf );
  240.     return ( BUFFER );
  241. }
  242.  
  243. int compress( char *inputfile, char *outputfile, char *n )
  244. {
  245.     FILE *fp_i;
  246.     BIT_FILE *fp_o;
  247.     schar *pcmbuf;
  248.     char header[32], proc[][4] = { "1A", "2A", "1B", "2B", "31A", "32A" },
  249.         *msg1 = "入力ファイル:           bytes",
  250.         *msg2 = "出力ファイル:           bytes",
  251.         *msg3 = "圧縮率      :       .   %";
  252.     int size, ds, rb, bits=40*8, pn, i, ret=0;
  253.  
  254.     pn = (int)n[0]-49;
  255.     if ( pn < 0 || 5 < pn )
  256.         { ret = 10; goto end4; }
  257.  
  258.     if ( ( pcmbuf = malloc( BUFFER ) ) == NULL )
  259.         { ret = 6; goto end4; }
  260.  
  261.     if ( ( fp_i = fopen( inputfile, "rb" ) ) == NULL )
  262.         { ret = 1; goto end3; }
  263.     if ( ( fp_o = BIT_open( outputfile, "wb" ) ) == NULL )
  264.         { ret = 2; goto end2; }
  265.  
  266.     if ( BIT_write_bytes( "PC\x01\x10", 4, 1, fp_o ) < 1 )
  267.         { ret = 4; goto end1; }
  268.     if ( BIT_write_bytes( proc[pn], 4, 1, fp_o ) < 1 )
  269.         { ret = 4; goto end1; }
  270.     if ( fread( header, 32, 1, fp_i ) < 1 )
  271.         { ret = 3; goto end1; }
  272.     if ( BIT_write_bytes( header, 32, 1, fp_o ) < 1 )
  273.         { ret = 4; goto end1; }
  274.  
  275.     size = DWORD( header+12 );
  276.  
  277.     /* FFTの準備 */
  278.     sin_cos();
  279.     bitrev();
  280.  
  281.     do    {
  282.         /* データ読み込み */
  283.         if ( ( rb = fread( pcmbuf, 1, BUFFER, fp_i ) ) < BUFFER )
  284.             _fill_b( pcmbuf+rb, 0x80, BUFFER-rb );
  285.         ds = BUFFER;
  286.         ctosc( pcmbuf, BUFFER );    /* PCM データを2の補数に変換 */
  287.  
  288.         /* encode */
  289.         for( i=0; proc[pn][i]; i++ )
  290.             switch( proc[pn][i] )
  291.                 {
  292.             case '1':
  293.                 predict( pcmbuf, ds );
  294.                 break;
  295.             case '2':
  296.                 dpcm( pcmbuf, ds );
  297.                 break;
  298.             case '3':
  299.                 if ( ( ds = fft_comp( pcmbuf ) ) == -1 )
  300.                     {
  301.                     if ( ds == -1 ) ret = 13;
  302.                     else if ( ds == -2 ) ret = 14;
  303.                     goto end1;
  304.                     }
  305.                 break;
  306.             case 'A':
  307.                 if ( ( ds = huff_comp( (char *)pcmbuf, ds, fp_o ) ) == -1 )
  308.                     { ret = 12; goto end1; }
  309.                 bits += ds*8;
  310.                 break;
  311.             case 'B':
  312.                 if ( ( ds = lzw_comp( (char *)pcmbuf, ds, fp_o ) ) < 0 )
  313.                     { ret = 11; goto end1; }
  314.                 bits += ds;
  315.                 }
  316.         size -= BUFFER;
  317.         }
  318.     while( size > 0 );
  319.  
  320.     bits = (bits+7)/8;
  321.     size = DWORD( header+12 )+32;
  322.     _to_dec( &msg1[13], size, 10 );
  323.     _to_dec( &msg2[13], bits, 10 );
  324.     if ( size > 100000000 )
  325.         _to_dec( &msg3[20], size/bits, 3 );
  326.     else
  327.         {
  328.         _to_dec( &msg3[17], bits*100/size, 3 );
  329.         _to_dec( &msg3[21], bits*10000/size, 2 );
  330.         }
  331.     puts( msg1 );
  332.     puts( msg2 );
  333.     puts( msg3 );
  334.  
  335. end1:BIT_close( fp_o );
  336. end2:fclose( fp_i );
  337. end3:free( pcmbuf );
  338. end4:return ( ret );
  339. }
  340.  
  341. int expand( char *inputfile, char *outputfile )
  342. {
  343.     BIT_FILE *fp_i;
  344.     FILE *fp_o;
  345.     int i, size, tmp, sw, ds, ret=0;
  346.     char header[32], proc[4];
  347.     schar *pcmbuf[2];
  348.  
  349.     if ( ( pcmbuf[0] = malloc( BUFFER*2 ) ) == NULL )
  350.         { ret = 6; goto end4; }
  351.     pcmbuf[1] = pcmbuf[0]+BUFFER;
  352.  
  353.     if ( ( fp_o = fopen( outputfile, "wb" ) ) == NULL )
  354.         { ret = 2; goto end3; }
  355.     if ( ( fp_i = BIT_open( inputfile, "rb" ) ) == NULL )
  356.         { ret = 1; goto end2; }
  357.  
  358.     if ( BIT_read_bytes( &tmp, 4, 1, fp_i ) < 1 )
  359.         { ret = 3; goto end1; }
  360.     if ( BIT_read_bytes( proc, 4, 1, fp_i ) < 1 )
  361.         { ret = 3; goto end1; }
  362.     if ( BIT_read_bytes( header, 32, 1, fp_i ) < 1 )
  363.         { ret = 3; goto end1; }
  364.     if ( fwrite( header, 32, 1, fp_o ) < 1 )
  365.         { ret = 4; goto end1; }
  366.  
  367.     size = DWORD( header+12 );
  368.  
  369.     _fill_b( pcmbuf[0], 0x80, BUFFER*2 );
  370.     for( i=_len(proc)-1; proc[i]!='3' && (i>=0); i-- )
  371.         switch( proc[i] )
  372.             {
  373.         case 'A':
  374.             ds = huff_exp( (char *)pcmbuf[0], fp_i );
  375.             break;
  376.         case 'B':
  377.             ds = lzw_exp( (char *)pcmbuf[0], fp_i );
  378.             break;
  379.         case '1':
  380.             predict_decode( pcmbuf[0], ds );
  381.             break;
  382.         case '2':
  383.             dpcm_decode( pcmbuf[0], ds );
  384.             }
  385.     sw = 1;
  386.  
  387.     do    {
  388.         /* read */
  389.         _fill_b( pcmbuf[sw], 0, BUFFER );
  390.         for( i=_len(proc)-1; proc[i]!='3' && (i>=0); i-- )
  391.             switch( proc[i] )
  392.                 {
  393.             case 'A':
  394.                 ds = huff_exp( (char *)pcmbuf[sw], fp_i );
  395.                 break;
  396.             case 'B':
  397.                 ds = lzw_exp( (char *)pcmbuf[sw], fp_i );
  398.                 break;
  399.             case '1':
  400.                 predict_decode( pcmbuf[sw], ds );
  401.                 break;
  402.             case '2':
  403.                 dpcm_decode( pcmbuf[sw], ds );
  404.                 }
  405.         sw ^= 1;
  406.  
  407.         /* decode */
  408.         if ( proc[i] == '3' )
  409.             if ( fft_exp( pcmbuf[sw], pcmbuf[1-sw][BUFFER/N] ) == -1 )
  410.                 { ret = 13; goto end1; }
  411.  
  412.         /* ファイルへ出力 */
  413.         sctoc( pcmbuf[sw], BUFFER );
  414.         if ( size < BUFFER )
  415.             {
  416.             if ( fwrite( pcmbuf[sw], size, 1, fp_o ) < 1 )
  417.                 { ret = 5; goto end1; }
  418.             }
  419.         else
  420.             if ( fwrite( pcmbuf[sw], BUFFER, 1, fp_o ) < 1 )
  421.                 { ret = 5; goto end1; }
  422.         size -= BUFFER;
  423.         }
  424.     while( size > 0 );
  425.  
  426. end1:BIT_close( fp_i );
  427. end2:fclose( fp_o );
  428. end3:free( pcmbuf[0] );
  429. end4:return ( ret );
  430. }
  431.